package slr.comment.portlet.ui;

import java.util.Arrays;
import java.util.List;

import slr.comment.model.SlrAnchor;
import slr.comment.model.SlrComment;
import slr.comment.model.impl.SlrCommentImpl;
import slr.comment.portlet.util.Lang;
import slr.comment.portlet.util.SLRCommentsUtil;
import slr.comment.service.SlrCommentLocalServiceUtil;

import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.OptionGroup;
import com.vaadin.ui.RichTextArea;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;

/**
 * The class is for the SlRCommentForm with the form fields.
 * 
 * @author TransIT mPower Labs
 * 
 */
@SuppressWarnings("serial")
public class SLRCommentForm extends FormLayout {

	final List<String> finrec = Arrays.asList(new String[] { "F", "R" });
	final List<String> posNeg = Arrays.asList(new String[] { "P", "N" });
	final RichTextArea editor = new RichTextArea(Lang.getKey("slr.comment.slr-comments"));
	final OptionGroup findRec = new OptionGroup(Lang.getKey("slr.comment.findings-or-recommendations"), finrec);
	final OptionGroup posNegCom = new OptionGroup(Lang.getKey("slr.comment.positive-or-negative"), posNeg);

	public SLRCommentForm(final SlrAnchor slrAnchor, final long slrDocId, final VerticalLayout second,
			final Window subwindow, SlrComment comment, final String type) {
		HorizontalLayout buttons = new HorizontalLayout();
		buttons.setSpacing(true);
		final Form commentForm = new Form();
		final SlrComment slrComment;

		if (com.liferay.portal.kernel.util.Validator.isNull(comment)) {
			slrComment = new SlrCommentImpl();
			commentForm.setCaption(Lang.getKey("slr.comment.add-slr-comment"));
			Button save = new Button(Lang.getKey("slr.comment.save-button"), new Button.ClickListener() {
				public void buttonClick(ClickEvent event) {
					try {
						int max = getMaxSLRCommentOrder(slrAnchor.getSlrAnchorId());
						SlrComment comment = new SlrCommentImpl();
						comment.setSlrAnchorId(slrAnchor.getSlrAnchorId());
						comment.setSlrCommentOrder(max + 1);
						comment.setSlrDocumentId(slrDocId);
						String slrCommTyp = (String) findRec.getValue();
						String slrCommStatus = StringPool.BLANK;
						String slrCommentText = editor.getValue().toString();
						if (slrCommTyp.equalsIgnoreCase("F")) {
							slrCommStatus = (String) posNegCom.getValue();
							if (Validator.isNull(slrCommentText) || Validator.isNull(slrCommTyp)
									|| Validator.isNull(posNegCom.getValue())) {
								subwindow.showNotification(Lang.getKey("slr.comment.all-fields-are-required"),
										Notification.TYPE_WARNING_MESSAGE);
								return;
							}

						} else if (Validator.isNull(slrCommentText) && Validator.isNull(slrCommTyp)) {
							subwindow.showNotification(Lang.getKey("slr.comment.all-fields-are-required"),
									Notification.TYPE_WARNING_MESSAGE);
							return;
						}
						comment.setSlrCommentTyp(slrCommTyp);
						comment.setSlrCommentStatus(slrCommStatus);

						comment.setSlrCommentText(slrCommentText);
						comment.setNew(true);
						SlrCommentLocalServiceUtil.addSlrComment(comment);
						replaceOldComponenet(slrAnchor, second, type);
						SLRCommentForm.this.getApplication().getMainWindow()
								.showNotification(Lang.getKey("slr.comment.successfully-added-record"));
						(subwindow.getParent()).removeWindow(subwindow);
					} catch (Exception e) {
						_log.error(e.getMessage());
						subwindow.showNotification(Lang.getKey("slr.comment.all-fields-are-required"));
					}

				}
			});

			buttons.addComponent(save);

			Button discardChanges = new Button(Lang.getKey("slr.comment.discard-button"), new Button.ClickListener() {
				public void buttonClick(ClickEvent event) {
					commentForm.discard();
				}
			});
			buttons.addComponent(discardChanges);
		} else {
			slrComment = comment;
			commentForm.setCaption(Lang.getKey("slr.comment.edit-slr-comment"));
			Button update = new Button(Lang.getKey("slr.comment.update-button"), new Button.ClickListener() {
				public void buttonClick(ClickEvent event) {
					if (com.liferay.portal.kernel.util.Validator.isNotNull(slrComment)) {
						try {
							int max = getMaxSLRCommentOrder(slrComment.getSlrAnchorId());

							String slrCommTyp = (String) findRec.getValue();
							if (!slrComment.getSlrCommentTyp().equalsIgnoreCase(slrCommTyp)) {
								slrComment.setSlrCommentOrder(max + 1);
							}
							String slrCommStatus = StringPool.BLANK;
							if (slrCommTyp.equalsIgnoreCase("F")) {
								slrCommStatus = (String) posNegCom.getValue();
							}
							slrComment.setSlrCommentText((String) editor.getValue());
							slrComment.setSlrCommentStatus(slrCommStatus);
							slrComment.setSlrCommentTyp(slrCommTyp);

							SlrCommentLocalServiceUtil.updateSlrComment(slrComment);
							replaceOldComponenet(slrAnchor, second, type);

							SLRCommentForm.this.getApplication().getMainWindow()
									.showNotification(Lang.getKey("slr.comment.successfully-updated-comment"));
							(subwindow.getParent()).removeWindow(subwindow);
						} catch (Exception e) {
							_log.error(e.getMessage());
							subwindow.showNotification(Lang.getKey("slr.comment.all-fields-are-required"));
						}

					}
				}
			});
			buttons.addComponent(update);

			Button delete = new Button(Lang.getKey("slr.comment.delete-button"), new Button.ClickListener() {

				public void buttonClick(ClickEvent event) {
					final Window confirmWindow = new Window(Lang.getKey("slr.comment.confirmation-dialog"));
					confirmWindow.setModal(true);
					confirmWindow.addComponent(new Label(Lang.getKey("slr.comment.confirm-delete-comment")));
					confirmWindow.center();
					confirmWindow.setWidth(20, UNITS_PERCENTAGE);
					confirmWindow.addComponent(new Button(Lang.getKey("slr.comment.yes-button"),
							new Button.ClickListener() {
								public void buttonClick(ClickEvent event) {
									if (com.liferay.portal.kernel.util.Validator.isNotNull(slrComment)) {
										try {
											SlrCommentLocalServiceUtil.deleteSlrComment(slrComment);
											subwindow.showNotification(Lang.getKey("slr.comment.comment-deleted"));
											confirmWindow.getParent().removeWindow(confirmWindow);
											replaceOldComponenet(slrAnchor, second, type);
										} catch (Exception e) {
											e.printStackTrace();
										}
									}
									SLRCommentForm.this.getApplication().getMainWindow()
											.showNotification(Lang.getKey("slr.comment.successfully-deleted-comment"));
									(subwindow.getParent()).removeWindow(subwindow);
								}
							}));
					confirmWindow.addComponent(new Button(Lang.getKey("slr.comment.no-button"),
							new Button.ClickListener() {

								public void buttonClick(ClickEvent event) {
									confirmWindow.getParent().removeWindow(confirmWindow);
									(subwindow.getParent()).removeWindow(subwindow);
								}
							}));
					SLRCommentForm.this.getApplication().getMainWindow().addWindow(confirmWindow);
				}
			});
			buttons.addComponent(delete);

		}

		if (slrComment.getSlrCommentTyp().equalsIgnoreCase("R")) {
			posNegCom.setEnabled(false);
		}
		BeanItem<SlrComment> slrCommentItem = new BeanItem<SlrComment>(slrComment);
		commentForm.setWriteThrough(false);
		commentForm.setInvalidCommitted(false);

		commentForm.setFormFieldFactory(new CommentFieldFactory());
		commentForm.setItemDataSource(slrCommentItem);

		commentForm.setVisibleItemProperties(Arrays.asList(new String[] { "slrCommentTyp", "slrCommentStatus",
				"slrCommentText" }));

		addComponent(commentForm);

		Button close = new Button("Quit", new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				(subwindow.getParent()).removeWindow(subwindow);
			}
		});
		buttons.addComponent(close);
		commentForm.getFooter().addComponent(buttons);
		commentForm.getFooter().setMargin(false, false, true, true);

	}

	private class CommentFieldFactory extends DefaultFieldFactory implements BlurListener {

		@Override
		public Field createField(Item item, Object propertyId, Component uiContext) {
			Field f;
			if ("slrCommentText".equals(propertyId)) {
				f = createEditorField(propertyId);
			} else if ("slrCommentTyp".equals(propertyId)) {
				f = createRadioField(propertyId);
			} else if ("slrCommentStatus".equals(propertyId)) {
				f = createRadioField(propertyId);
			} else {
				f = super.createField(item, propertyId, uiContext);
			}
			f.setRequired(true);
			f.setRequiredError(Lang.getKey("slr.comment.successfully-deleted-comment"));
			return f;
		}

		private Field createEditorField(Object propertyId) {
			editor.setCaption(DefaultFieldFactory.createCaptionByPropertyId(propertyId));
			return editor;
		}

		private Field createRadioField(Object propertyId) {
			if ("slrCommentTyp".equals(propertyId)) {
				findRec.addListener(this);
				return findRec;
			} else {
				return posNegCom;
			}

		}

		@Override
		public void blur(BlurEvent event) {
			if (event.getSource().toString().equalsIgnoreCase("R")) {
				posNegCom.setEnabled(false);
			} else {
				posNegCom.setEnabled(true);
			}
		}

	}

	/**
	 * After update or delete of the SLRComment the container is refreshed.
	 * 
	 * @param slrAnchor
	 * @param second
	 * @param type
	 */
	public static void replaceOldComponenet(SlrAnchor slrAnchor, VerticalLayout second, String type) {
		List<SlrComment> slrCommentList = null;

		try {
			slrCommentList = SlrCommentLocalServiceUtil.findByCommentTypAndAnchorId(type, slrAnchor.getSlrAnchorId());

			SLRCommentsTable firstComponent = new SLRCommentsTable();
			SLRCommentsUtil commentsUtil = new SLRCommentsUtil();
			second.replaceComponent(second.getComponent(0),
					firstComponent.addCommentListComponent(slrAnchor, slrCommentList, second));
			second.replaceComponent(second.getComponent(1), commentsUtil.getButtons(firstComponent, slrAnchor,
					SLRCommentsUtil.getSlrDocId(slrAnchor), second, type));

		} catch (Exception e) {
			_log.error(e.getMessage());
		}

	}

	/**
	 * get the Maximum CommentOrder of the SLRComments
	 * 
	 * @param slrAnchorId
	 * @return int commentOrder.
	 */
	private int getMaxSLRCommentOrder(long slrAnchorId) {
		DynamicQuery query = DynamicQueryFactoryUtil.forClass(SlrComment.class);
		query.add(RestrictionsFactoryUtil.eq("SlrCommentTyp", (String) findRec.getValue()));
		query.add(RestrictionsFactoryUtil.eq("SlrAnchorId", slrAnchorId));
		int max = 0;
		query.setProjection(ProjectionFactoryUtil.max("SlrCommentOrder"));
		try {
			max = (Integer) SlrCommentLocalServiceUtil.dynamicQuery(query).get(0);
		} catch (SystemException e) {
			_log.error(e.getMessage());
		}
		return max;
	}

	private static Log _log = LogFactoryUtil.getLog(SLRCommentForm.class);
}
